﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.ComponentModel;
using System.Windows.Forms.DataVisualization.Charting;

namespace ProfilerPOC
{
    
    
    class ProcessLaunchAndMonitor
    {

        Process p = new Process();
        ProcessStartInfo startInfo = new ProcessStartInfo();
        PerformanceCounter cpuPerformanceCounter = new PerformanceCounter();
        PerformanceCounter MemPerformanceCounter = new PerformanceCounter();
        Instrumentor Inst = new Instrumentor();

        DataPoint CPUdataPoint = new System.Windows.Forms.DataVisualization.Charting.DataPoint();
        DataPoint MemDataPoint = new System.Windows.Forms.DataVisualization.Charting.DataPoint();

        DataPoint[] CounterArray = new DataPoint[2];

        float cpuValue, memValue;
        double t = 0;
        
        public event EventHandler RaiseOutputReceived;
        public event EventHandler PerfDataUpdated;
        public event EventHandler RaiseProfilerStatement;

        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

        private DataPoint g_cpuDP = new DataPoint();
        private DataPoint g_memDP = new DataPoint();

        public string updatedFilePath = Environment.GetEnvironmentVariable("LocalAppData");


   
    public DataPoint CPU_DP
    {
        get { return g_cpuDP; }
        set { value = g_cpuDP; }
    }

    public DataPoint MEM_DP
    {
        get { return g_memDP; }
        set { value = g_memDP; }
    }

        
    
    public void SpinUpProcess()
    {

        timer.Tick += new EventHandler(timer_Tick);
        timer.Interval = 250;

        
                
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardError = true;
        startInfo.RedirectStandardOutput = true;
        startInfo.CreateNoWindow = true;
        startInfo.Arguments = "-ExecutionPolicy ByPass -File " + updatedFilePath + @"\PoSHProfilerScript.ps1";
        
        startInfo.FileName = @"c:\windows\System32\WindowsPowershell\v1.0\powershell.exe";

        cpuPerformanceCounter.CategoryName = "Process";
        cpuPerformanceCounter.CounterName = "% Processor Time";
        MemPerformanceCounter.CategoryName = "Process";
        MemPerformanceCounter.CounterName = "Working Set";

        p.StartInfo = startInfo;
        p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
        p.Start();
        p.BeginOutputReadLine();
        p.EnableRaisingEvents = true;
        cpuPerformanceCounter.InstanceName = GetInstanceName(p.Id);
        MemPerformanceCounter.InstanceName = GetInstanceName(p.Id);
        timer.Start();
        

    }

    void p_OutputDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
    {
        if (!String.IsNullOrEmpty(outLine.Data))
        {
            if (outLine.Data.StartsWith("PoshProfiler:"))
            {
                OnRaiseProfilerStatement(outLine.Data.Replace("PoshProfiler:", ""), new EventArgs());
            }
            else
            {
                OnRaiseOutputReceived(outLine.Data, new EventArgs());
            }
            
            
            
        }
    }

    protected virtual void OnRaiseProfilerStatement(object sender, EventArgs e)
    {
        if (RaiseProfilerStatement != null)
        {
            
            RaiseProfilerStatement(sender, e);
        }
    }

    protected virtual void OnRaiseOutputReceived(object sender, EventArgs e)
    {
        if (RaiseOutputReceived != null)
        {
            RaiseOutputReceived(sender, e);
        }
    }

    protected virtual void OnPerfDataUpdated(object sender, EventArgs e)
    {
        if (PerfDataUpdated != null)
        {
            PerfDataUpdated(sender, e);
        }
    }

    
    private string GetInstanceName(int pid)
    {
        PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");

        string[] instances = cat.GetInstanceNames();

        foreach (string instance in instances)
        {
            using (PerformanceCounter cnt = new PerformanceCounter("Process", "ID Process",instance, true))
            {
                try
                {
                    int val = (int)cnt.RawValue;
                    if (val == pid)
                    {
                        return instance;
                    }
                }
                catch (System.InvalidOperationException)
                {
                    //we don't need to handle this right now.
                }
                
            }
        }//end foreach
        throw new Exception("Process not found..");
                       
    }//end GetInstanceName()

    void timer_Tick(object sender, EventArgs e)
    {
        timer.Stop();

        if (!p.HasExited)
        {
            cpuValue = cpuPerformanceCounter.NextValue();
            memValue = (MemPerformanceCounter.RawValue /1024) / 1024;

            g_cpuDP.XValue = t;
            g_cpuDP.YValues[0] = cpuValue;

            g_memDP.XValue = t;
            g_memDP.YValues[0] = memValue;
            
           
            OnPerfDataUpdated(null, new EventArgs());
            
            t++;
            timer.Enabled = true;
                
                
        }//end if
            
            

   }//end timer_Tick

           


    }
}//end namespace
